Option Strict Off
Option Explicit On
Module RemoveLastFrame
	'This routins removes the last frame of an .avi file
	'call it using a function call Ret1 = DeleteLastFrame(TargetFile) it returns a boolean value true if it succeeds
	
	Private Const GENERIC_READ_WRITE As Integer = &HC0000000
	Private Const OPEN_EXISTING As Integer = 3
	Private Const FILE_ATTRIBUTE_NORMAL As Integer = &H80
	Private Const FILE_BEGIN As Integer = 0
	
	Private Structure SECURITY_ATTRIBUTES
		Dim nLength As Integer
		Dim lpSecurityDescriptor As Integer
		Dim bInheritHandle As Integer
	End Structure
	
	'UPGRADE_WARNING: Structure SECURITY_ATTRIBUTES may require marshalling attributes to be passed as an argument in this Declare statement. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="C429C3A5-5D47-4CD9-8F51-74A1616405DC"'
	Private Declare Function CreateFile Lib "kernel32"  Alias "CreateFileA"(ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Integer, ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As Integer) As Integer
	Private Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Integer, ByVal lDistanceToMove As Integer, ByRef lpDistanceToMoveHigh As Integer, ByVal dwMoveMethod As Integer) As Integer
	Private Declare Function SetEndOfFile Lib "kernel32" (ByVal hFile As Integer) As Integer
	Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Integer) As Integer
	
	Dim ReadinData1 As Integer 'holds the value read in from the file
	Dim MoviStart As Integer 'holds where the "Movi" line starts
	Dim idx1Start As Integer 'holds where the "idx1" index starts
	Dim TotNumFrames As Integer 'The total number of frames in the file
	Dim LastFrameStart As Integer 'The position in the file where the last frame starts
	Dim LastFrameLength As Integer 'How long the last frame frame data is
	Dim Result As Boolean 'The returned value from the function
	Dim ByteValue As Byte 'A variable to hold a single byte, used throughout the module as a temporary store
	Dim FileHandle As Integer
	Dim Ret As Integer
	Dim SA As SECURITY_ATTRIBUTES
	Public Function DeleteLastFrame(ByRef FileToTarget As String) As Boolean
		Dim i As Integer 'A simple loop counter
		Dim ReturnCheck As Boolean
		Dim EndPointOfNewFile As Integer
		Dim ByteAdded As Boolean
		
		DeleteLastFrame = False 'Set the function to initially return an error
		'UPGRADE_WARNING: Dir has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		If Dir(FileToTarget) = "" Then Exit Function 'If the file doesn't exist, exit the function
		
		FileOpen(10, FileToTarget, OpenMode.Binary) 'Open the avi file
		Result = GetRefPoints 'Get all the relevant points within the file.
		If TotNumFrames < 2 Then 'Check if there is only one frame in the .avi file
			Call MsgBox("I cannot delete the first frame of an .avi file", MsgBoxStyle.OKOnly + MsgBoxStyle.Exclamation, "Helium Frog Animator")
			Exit Function
		End If
		
		'UPGRADE_WARNING: Dir has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		If Dir(My.Application.Info.DirectoryPath & "\TempIndex.txt") <> "" Then Kill((My.Application.Info.DirectoryPath & "\TempIndex.txt")) 'Erase any previous file that holds the temporary index data
		
		FileOpen(11, My.Application.Info.DirectoryPath & "\TempIndex.txt", OpenMode.Binary) 'Open up a temporary file for index data
		For i = idx1Start + 1 To idx1Start + ((TotNumFrames * 16) + 8 - 16) 'Loop through all the index bytes and copy them to the index store. Exclude the last frame info
			'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
			FileGet(10, ByteValue, i) 'Get the value from the file at the old location
			'UPGRADE_WARNING: Put was upgraded to FilePut and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
			FilePut(11, ByteValue) 'Copy it to the index store file.
		Next i
		'UPGRADE_WARNING: Put was upgraded to FilePut and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FilePut(11, CInt((TotNumFrames - 1) * 16), 4 + 1) 'Store the length of the new index file in the line after the idx1 header
		FileClose(11) 'Close the index store file.
		
		FileClose(10) 'Close the .avi file so that it can be truncated with API call
		
		'Now truncate the file using API calls
		FileHandle = CreateFile(FileToTarget, GENERIC_READ_WRITE, 0, SA, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0) 'Open the existing file using an API call this gets the file handle.
		Ret = SetFilePointer(FileHandle, LastFrameStart, 0, FILE_BEGIN) 'Move pointer to where you want to truncate
		SetEndOfFile(FileHandle) 'Truncate the file
		CloseHandle(FileHandle) 'Close the file
		
		FileOpen(10, FileToTarget, OpenMode.Binary) 'Reopen the avi file using standard VB commands
		
		'check here whether the file length is exactly divisible by 2 (Format states it must be rounded to a WORD boundary ie 2 bytes)
		If LOF(10) Mod 2 <> 0 Then 'Divide the length by 2 and find the remainder
			'UPGRADE_WARNING: Put was upgraded to FilePut and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
			FilePut(10, CByte(1), LOF(10) + 1) 'The data length is not divisable exactly by 2 so add a padding byte (has value of 01 for some reason)
			'  Debug.Print "1 Padding Byte Added"
			ByteAdded = True 'Set the flag to say that a padding byte has been added
		Else
			'  Debug.Print "No Padding Bytes Added"
			ByteAdded = False 'Set the flag to say that a padding byte has not been added
		End If
		EndPointOfNewFile = LOF(10) 'Get the new file length
		
		FileOpen(11, My.Application.Info.DirectoryPath & "\TempIndex.txt", OpenMode.Binary) 'reopen up a temporary file for index data
		For i = 1 To LOF(11) 'write the new index data from the IndexStore file to the end of the Motion Jpeg file
			'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
			FileGet(11, ByteValue, i) 'Get the value from the index file
			'UPGRADE_WARNING: Put was upgraded to FilePut and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
			FilePut(10, ByteValue, EndPointOfNewFile + i) 'Write it to the end of the file
		Next i
		FileClose(11) 'Close the index store file
		Kill((My.Application.Info.DirectoryPath & "\TempIndex.txt")) 'Delete the temporary index file.
		
		'UPGRADE_WARNING: Put was upgraded to FilePut and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FilePut(10, CInt(LOF(10) - 8), 4 + 1) 'Set the total length of the file in header. This is total file length minus the first 8 bytes
		'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FileGet(10, ReadinData1, 48 + 1) 'Get the total number of frames in the file
		'UPGRADE_WARNING: Put was upgraded to FilePut and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FilePut(10, CInt(ReadinData1 - 1), 48 + 1) 'Set the total number of frames in header to one frame less
		'UPGRADE_WARNING: Put was upgraded to FilePut and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FilePut(10, CInt(ReadinData1 - 1), 140 + 1) 'Set the total number of frames in the AVIStreamheader structure to one less
		'UPGRADE_WARNING: Put was upgraded to FilePut and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FilePut(10, CInt(EndPointOfNewFile - MoviStart), 2552 + 1) 'calculate and store the new total data length, this is the distance between "Movi" and the end of the data.
		FileClose(10) 'Close the .avi file
		
		DeleteLastFrame = True 'Return Ok / True
	End Function
	
	
	Private Function GetRefPoints() As Boolean
		'This subroutine gets vital points in the avi file, such as where the movi data and index start positions are. It returns the points to variables MoviStart and idx1Start
		'It also does some error checking
		GetRefPoints = False 'Initially tell the function to return an error
		'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FileGet(10, ReadinData1, 112 + 1) 'Get the data that specifies what type of file we have
		If ReadinData1 = &H47504A4D Then 'Check if data contains "MJPG"
			'  Debug.Print "This is a motion jpeg file"
		Else
			Call MsgBox("This doesn't appear to be a Motion Jpeg file" & " but contains " & "&H" & Hex(ReadinData1), MsgBoxStyle.OKOnly + MsgBoxStyle.Exclamation, "Helium Frog Animator")
			Exit Function
		End If
		
		'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FileGet(10, ReadinData1, 248 + 1) 'Get the data that specifies the start of the junk header
		If ReadinData1 = &H4B4E554A Then 'Check if data contains "JUNK"
			'  Debug.Print "The junk header starts at byte &Hf8"
		Else
			Call MsgBox("I cannot find the Junk Header but found hex value " & "&H" & Hex(ReadinData1), MsgBoxStyle.OKOnly + MsgBoxStyle.Exclamation, "Helium Frog Animator")
			Exit Function
		End If
		
		'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FileGet(10, ReadinData1, 252 + 1) 'Get the length of the junk header
		MoviStart = 264 + ReadinData1 'Calculate where "movi" line should be
		'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FileGet(10, ReadinData1, MoviStart + 1) 'Extract data from that line
		If ReadinData1 = &H69766F6D Then 'Check if data contains "movi"
			'  Debug.Print "The movi header starts at byte " & "&H" & Hex$(MoviStart)
		Else
			Call MsgBox("I cannot find the movi header but found hex value " & "&H" & Hex(ReadinData1), MsgBoxStyle.OKOnly + MsgBoxStyle.Exclamation, "Helium Frog Animator")
			Exit Function
		End If
		
		'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FileGet(10, ReadinData1, MoviStart - 4 + 1) 'Get the length of the movi data
		idx1Start = MoviStart + ReadinData1 'Calculate where "idx1" line should be
		'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FileGet(10, ReadinData1, idx1Start + 1) 'Extract data from that line
		If ReadinData1 = &H31786469 Then 'Check if data contains "idx1"
			'  Debug.Print "The idx1 header starts at byte " & "&H" & Hex$(idx1Start)
		Else
			Call MsgBox("I cannot find the idx1 header but found hex value " & "&H" & Hex(ReadinData1), MsgBoxStyle.OKOnly + MsgBoxStyle.Exclamation, "Helium Frog Animator")
			Exit Function
		End If
		
		'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FileGet(10, TotNumFrames, 48 + 1) 'Get the total number of frames as specified in the header
		'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FileGet(10, ReadinData1, idx1Start + 4 + 1) 'get the length of the index in bytes
		If TotNumFrames = ReadinData1 / 16 Then 'The each frame in the index occupies 16 bytes, so check it is the correct length
			'  Debug.Print "There are a total of " & TotNumFrames & " frames in the file"
		Else
			Call MsgBox("The index length does not appear to match the number of frames in the header!" & Chr(13) & Chr(10) & "Header says " & TotNumFrames & Chr(13) & Chr(10) & "Index has " & ReadinData1 / 16, MsgBoxStyle.OKOnly + MsgBoxStyle.Exclamation, "Helium Frog Animator")
			Exit Function
		End If
		
		'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
		FileGet(10, ReadinData1, idx1Start + 1 + 8 + ((TotNumFrames - 1) * 16)) 'Find the last frame data
		If ReadinData1 = &H62643030 Then 'Check if data contains "00db"
			'  Debug.Print "I have found the last frame data " & "&H" & Hex$(ReadinData1)
			'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
			FileGet(10, LastFrameStart, idx1Start + 1 + 16 + ((TotNumFrames - 1) * 16)) 'Read in the last frame data offset from the index data
			'  Debug.Print "last frame offset is" & "&H" & Hex$(LastFrameStart)
			'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
			FileGet(10, LastFrameLength, idx1Start + 1 + 20 + ((TotNumFrames - 1) * 16)) 'Read in the last frame data length
			'  Debug.Print "last frame length is" & "&H" & Hex$(LastFrameLength)
		Else
			Call MsgBox("I cannot find the last frame data header but found hex value " & "&H" & Hex(ReadinData1), MsgBoxStyle.OKOnly + MsgBoxStyle.Exclamation, "Helium Frog Animator")
			Exit Function
		End If
		
		GetRefPoints = True 'All is Ok so tell main program
		
	End Function
End Module